﻿#include "stdafx.h"
#include "WatchView.h"
#include "VariableWatch.h"
#include <wx/sizer.h>

LUA_DEBUG_BEGIN

/*-----------------------------------------------------------------*/
BEGIN_EVENT_TABLE(WatchView, wxPanel)
EVT_SHOW(WatchView::OnShow)
EVT_DEBUG_CHANGED_STATE(wxID_ANY, WatchView::OnChangedState)
EVT_DEBUG_UPDATE_SOURCE(wxID_ANY, WatchView::OnUpdateSource)
EVT_DEBUG_FOCUS_BACKTRACELINE(wxID_ANY, WatchView::OnFocusBacktraceLine)
END_EVENT_TABLE()

static int GetWatchViewId(WatchView::Type type)
{
    switch (type)
    {
    case WatchView::TYPE_LOCALWATCH:
        return ID_LOCALWATCHVIEW;
    case WatchView::TYPE_GLOBALWATCH:
        return ID_GLOBALWATCHVIEW;
    case WatchView::TYPE_REGISTRYWATCH:
        return ID_REGISTRYWATCHVIEW;
    case WatchView::TYPE_ENVIRONWATCH:
        return ID_ENVIRONWATCHVIEW;
    case WatchView::TYPE_STACKWATCH:
        return ID_STACKWATCHVIEW;
    case WatchView::TYPE_WATCH:
        return ID_WATCHVIEW;
    }

    return -1;
}

struct VarUpdateRequester {
    explicit VarUpdateRequester(Mediator_ptr mediator,WatchView::Type type)
        : m_mediator(mediator),m_type(type) {
    }
    void operator()(const LuaVarListCallback &callback) {
        switch (m_type)
        {
        case WatchView::TYPE_LOCALWATCH:
            m_mediator->GetEngine()->SendRequestLocalVarList(
                m_mediator->GetStackFrame(),true, true, false, callback);
            break;
        case WatchView::TYPE_ENVIRONWATCH:
            m_mediator->GetEngine()->SendRequestLocalVarList(
                m_mediator->GetStackFrame(),false, false, true, callback);
            break;
        case WatchView::TYPE_GLOBALWATCH:
            m_mediator->GetEngine()->SendRequestGlobalVarList(callback);
            break;
        case WatchView::TYPE_REGISTRYWATCH:
            m_mediator->GetEngine()->SendRequestRegistryVarList(callback);
            break;
        case WatchView::TYPE_STACKWATCH:
            m_mediator->GetEngine()->SendRequestStackList(callback);
            break;
        case WatchView::TYPE_WATCH:
            wxASSERT(false);
            break;
        }
    }

private:
    Mediator_ptr m_mediator;
    WatchView::Type m_type;
};

WatchView::WatchView(Mediator_ptr mediator,wxWindow *parent,Type type) :
wxPanel(parent, GetWatchViewId(type)),
m_mediator(mediator),
m_type(type)
{
    if (type == TYPE_WATCH) {
        m_watch = new VariableWatch(m_mediator, this, wxID_ANY, true, true,true, true, VarListRequester());
    }
    else {
        m_watch = new VariableWatch(m_mediator, this, wxID_ANY, true, true,false, false,
            VarUpdateRequester(m_mediator, m_type));
    }

    wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
    sizer->Add(m_watch, 1, wxEXPAND);
    SetSizer(sizer);
    sizer->SetSizeHints(this);
}

WatchView::~WatchView() {
}

void WatchView::BeginUpdating() {
    m_watch->BeginUpdating();
}

void WatchView::OnChangedState(wxDebugEvent &event) {
    event.Skip();

    Enable(event.IsBreak());
}

void WatchView::OnUpdateSource(wxDebugEvent &event) {
    event.Skip();

    if (IsEnabled() && IsShown()) {
        BeginUpdating();
    }
}

void WatchView::OnFocusBacktraceLine(wxDebugEvent &event) {
    event.Skip();

    if (IsEnabled() && IsShown()) {
        BeginUpdating();
    }
}

void WatchView::OnShow(wxShowEvent &event) {
    event.Skip();

    if (event.IsShown() && IsEnabled() && IsShown()) {
        BeginUpdating();
    }
}

LUA_DEBUG_END
